<?php


namespace app\common\facades\auth\provider;


use app\common\facades\auth\cache\AuthCache;
use app\common\facades\auth\contract\AuthContract;
use app\common\models\Admin;
use app\common\models\User;
use Carbon\Carbon;
use thans\jwt\facade\JWTAuth;

class AuthProvider implements AuthContract
{
    private $guard = 'api';
    private $token;
    private $user_id = 0;
    private $uuid = '';

    public function login($user)
    {
        return $this->createUuid()->bindUserIdToUuid($user->id)->createTokenByUuid();
    }

    public function logout()
    {
        $this->getToken()->resolveUuidFromToken()->removeUserFromCache();
        JWTAuth::invalidate($this->token);
        return true;
    }

    private function createTokenByUuid()
    {
        return JWTAuth::builder(['uuid' => $this->uuid]);
    }

    private function getToken()
    {
        $token = request()->header('Authorization', '');
        $this->token = explode(' ', $token)[1];
        return $this;
    }

    public function user()
    {
        return $this->resolveUuidFromToken()->getUserIdByUuid()->queryUserByIdFromDB();
    }

    public function queryUserByIdFromDB()
    {
        if ($this->guard == 'api'){
            return User::find($this->user_id);
        }
        if ($this->guard == 'admin'){
            return Admin::find($this->user_id);
        }
    }

    public function guard(string $guard = 'api')
    {
        $this->guard = $guard;
        return $this;
    }

    private function resolveUuidFromToken()
    {
        $payload = json_decode(json_encode(JWTAuth::getPayload()),true);
        $this->uuid = $payload['uuid'];
        return $this;
    }

    private function getUserIdByUuid()
    {
        $this->user_id = AuthCache::getUser($this->guard, $this->uuid);
        return $this;
    }

    private function bindUserIdToUuid(int $user_id)
    {
        AuthCache::setUser($this->guard, $this->uuid, $user_id);
        return $this;
    }

    private function createUuid()
    {
        $this->uuid = md5(md5(Carbon::now()->getPreciseTimestamp() . mt_rand(1000000, 9999999)));
        return $this;
    }

    private function removeUserFromCache()
    {
        return AuthCache::delUser($this->guard, $this->uuid);
    }
}
